from langchain.prompts  import PromptTemplate,ChatPromptTemplate,HumanMessagePromptTemplate

from langchain.chat_models import ChatOpenAI
# auto Fixing Parser
# 利用LLM自动解析异常并重新解析
from langchain.output_parsers import PydanticOutputParser,OutputFixingParser
from pydantic_data import Data
from dotenv import load_dotenv,find_dotenv






_ =load_dotenv(find_dotenv());

model_name ='gpt-4'
temperature = 0
model = ChatOpenAI(model_name=model_name,temperature=temperature)


# 依据pydantic对象的定义，构造一个outputParser
parser = PydanticOutputParser(pydantic_object=Data)

teplate = """提取用户输出中的日期
{format_instructions}
用户输出：
{query}"""

"""input_variables 是必须要由用户提供的信息。LangChain 将会使用这些信息来生成文本。

partial_variables 是可以由 LangChain 从其他变量中推断出来的信息。如果用户没有提供这些信息，LangChain 将会使用推断出来的值。"""
prompt = PromptTemplate(
  template = teplate,
  input_variables = ["query"],
  # 直接从outputparser中获取描述，并对模板的变量预先赋值
  partial_variables = {"format_instructions": parser.get_format_instructions}
)


print("===pormat Instruction====")
print(parser.get_format_instructions())

# 完整的模板
query = '2023年四月4日天气大雨'
modle_input = prompt.format_prompt(query=query)
print("===完整的模板====")
print(modle_input)


output= model(modle_input.to_messages())
print("===模型的输出====")
print(output)
data = parser.parse(output.content)
print("===解析后的数据====")
# 将json数据转化为data 数据
print(data)



# 创建一个修复器
fixer = OutputFixingParser.from_llm(llm=model, parser=parser)

# 我们把之前的outtput格式改错
output = output.content.replace("4", "四")
print("===修复后的输出====")
print(output)
try:
    data = parser.parse(output)
except Exception as e:
    print("===解析失败====")
    print(e)

# 用outputFixingParser自动修复
data = fixer.parse(output)
print("===修复后的数据====")
print (data)